home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / Xconq 7.0d16 / doc / hacking.texi < prev    next >
Encoding:
Text File  |  1993-12-20  |  28.0 KB  |  724 lines  |  [TEXT/MPS ]

  1.  
  2. @node Hacking Xconq, Glossary, Design Hints, Top
  3.  
  4. @chapter Hacking Xconq
  5.  
  6. Despite its high degree of flexibility, you may decide that you must modify
  7. the @i{Xconq} program itself.  You should know what you are doing;
  8. @i{Xconq} is designed to be modifiable, but it is not simple code.
  9. In the past, people have found it easy to make changes,
  10. but much harder to make them correctly!
  11.  
  12. @i{Xconq} is designed to be portable to different types of user interfaces.
  13. It is based on a kernel-interface architecture, where the semantics of
  14. the game, as documented in the preceding chapters, is part of the kernel,
  15. while the main program and player interaction are specific to each system.
  16.  
  17. Don't let interfaces ever set kernel object values directly, always
  18. go through calls that can be siphoned for networking.
  19.  
  20. @menu
  21. * Kernel::
  22. * Interface::
  23. * Ideas::
  24. @end menu
  25.  
  26. @node Kernel, Interface, Porting Xconq, Porting Xconq
  27.  
  28. @section Kernel
  29.  
  30. The kernel is the part of @i{Xconq} shared by all interfaces.
  31. It does no I/O except to files or for debugging.
  32.  
  33. Specifically, the kernel supplies these functions:
  34. @itemize
  35. @item
  36. Data structure initialization. (@code{init_data_structures})
  37.  
  38. @item
  39. Game module loading and interpretation. (@code{load_game_module})
  40.  
  41. @item
  42. Initial player/side setup. (@code{make_trial_assignments})
  43.  
  44. @item
  45. Synthesis methods. (@code{run_synthesis_methods})
  46.  
  47. @item
  48. Final player/side setup. (@code{make_assignments})
  49.  
  50. @item
  51. Game execution. (@code{run_game})
  52.  
  53. @item
  54. Implementations of unit actions.
  55.  
  56. @item
  57. AI players.
  58.  
  59. @item
  60. Help Info (@code{get_help_text})
  61.  
  62. @item
  63. Game saving and scorekeeping.
  64. @end itemize
  65.  
  66. @subsection Porting the Kernel
  67.  
  68. The kernel should be restricted to ANSI C, and should avoid or optionalize
  69. the less common features (like prototypes).
  70. Although the kernel uses stdio,
  71. it cannot assume the presence of a console (stdin, stdout, stderr).
  72.  
  73. You should be careful about memory consumption.  In general, the kernel
  74. takes the attitude that if it was worth allocating, it's worth hanging
  75. onto; and so the program does not free much storage.  Also, nearly all
  76. of the allocation happens during startup.  Since a game may run for a
  77. very long time (thousands of turns perhaps), it is important not to
  78. run the risk of exhausting memory at a climactic moment in the game!
  79.  
  80. @subsection Writing New Synthesis Methods
  81.  
  82. You can add new synthesis methods to @i{Xconq}.
  83. This may be necessary if an external program is
  84. does not exist or is unsuitable.
  85. Synthesis methods should start out by testing whether or not to run,
  86. and should never assume that any other method has been run before or
  87. after, nor that any particular game module has been loaded.
  88. However, ``tricks'' are usually OK, such as setting a particular global
  89. variable in a particular module only, then having the synthesis method
  90. test whether that global is set.
  91. See the file @code{init.c} for further details.
  92.  
  93. Synthesis methods that take longer than a second or two to execute
  94. should generate percent-done info for the interface to use,
  95. via the function @code{announce_progress}.
  96. Be aware that most methods will be O(n) or O(n*n) on the
  97. size of the world or the number of units,
  98. so they can take much longer to set up
  99. a large game than a small one.
  100. Also, @i{Xconq} may be running on a much smaller and slower
  101. machine than what you're using now.
  102. (Players will often go overboard and start up giant games too.)
  103.  
  104. @subsection Writing New Namers
  105.  
  106. [describe hook and interface]
  107.  
  108. @subsection Writing New AIs
  109.  
  110. You can add new types of AIs to @i{Xconq}.
  111. You would do this to add different strategies as well as
  112. to add AIs that are programmed specifically for a single game or
  113. class of games.  (This is useful because the generic AI does not
  114. always understand the appropriate strategy for each game.)
  115.  
  116. You have to design the object that is the AI's ``mental state''.
  117. If your AI need only react to the immediate situation, then this
  118. object can be very simple, but in general you will need to design
  119. a fairly elaborate structure with a number of substructures.
  120. Since there may be several AIs in a single game, you should be
  121. careful about using globals, and since @i{Xconq} games may often
  122. run for a long time, you should be careful not to consume memory
  123. recklessly.
  124.  
  125. @itemize
  126. @item
  127. Name.
  128.  
  129. @item
  130. Validity function.  This runs after modules are loaded, and during player/side
  131. setup, and decides whether it can be in the given game on the given side.
  132. [have a chain of fallback AIs, or blow off the game?]
  133.  
  134. @item
  135. Game init function.  This runs before displays are set up, just in case
  136. a display examines the AI's state.
  137.  
  138. @item
  139. Turn init function.  This runs after all the units get their acp and mp
  140. for the turn, but before anybody actually gets to move.
  141.  
  142. @item
  143. Unit order function.  This gets run to decide what the unit should do.
  144. Usually it should be allowed to follow its plan.
  145. [do separate fns for before and after plan execution?]
  146.  
  147. @item
  148. Event reaction functions. [how many?]
  149.  
  150. @end itemize
  151.  
  152. Note that these functions have very few constraints, so you can write them
  153. to work together in various ways.  For instance, an AI can decide whether
  154. to resign once/turn, once/action, or once for each 4 units it moves, every
  155. other turn.
  156.  
  157. @node Interface, Ideas, Kernel, Porting Xconq
  158.  
  159. @section Interface
  160.  
  161. The player interface is how actual players interact with the game.
  162. It need not be graphical or even particularly interactive,
  163. in fact it could even be a network server-style interface!
  164. However, this section will concentrate on the construction
  165. of interactive graphical interfaces.
  166.  
  167. An interface is always compiled in, so it has complete access to the
  168. game state.  However, if your version of @i{Xconq} has any networking
  169. support, the interface should not modify kernel structures directly,
  170. but should instead use kernel routines.  The kernel routines will
  171. forward any state modifications to all other programs participating
  172. in a game, so that everybody's state remains consistent.
  173.  
  174. A working interface must provide some level of capability in each
  175. of these areas:
  176.  
  177. @itemize
  178. @item
  179. Main program.
  180. The interface includes the main application and any
  181. system-specific infrastructure, such as event handling.
  182.  
  183. @item
  184. Interpretation of startup options.
  185. This includes choice of games, variants, and players.
  186.  
  187. @item
  188. Display of game state.
  189. This includes both textual and graphical displays,
  190. both static and dynamic.
  191.  
  192. @item
  193. Commands/gestures for unit tasks and actions,
  194. and for general state modifications.
  195.  
  196. @item
  197. Display update in response to state changes.
  198.  
  199. @item
  200. Realtime progress.
  201. Some game designs require the interface
  202. to support realtime.
  203. @end itemize
  204.  
  205. @subsection Main Program
  206.  
  207. The interface actually provides the ``main program'' for
  208. @i{Xconq}; this allows maximum flexibility in adapting
  209. to different environments.
  210.  
  211. Once a game is underway, the interface is in a sense self-contained,
  212. needing only to call @code{run_game} periodically to keep the
  213. game moving along.  @code{run_game} takes one argument which can
  214. be -1, 0, or 1.  If 1, then one unit gets to do one action, then
  215. the routine returns.  If 0, the calculations are gone through, but
  216. no units can move.  If -1, then all possible units will move before
  217. @code{run_game} returns.  This last case is not recommended for interactive
  218. programs, since moving all units in a large game may take a very long
  219. time; several minutes sometimes. 
  220.  
  221. [When networking, all kernels must call with same values...]
  222.  
  223. @subsection Startup Options
  224.  
  225.  
  226. @subsection Progress Indication
  227.  
  228. Some synthesis methods are very slow, and become even
  229. slow when creating large games, so the kernel will announce a slow process,
  230. provide regular updates, and signal when the process is done.  The interface
  231. should display this in some useful way.  In general, progress should always
  232. be displayed, although one could postpone displaying anything until after
  233. the first progress update, calculate an estimated time to completion, and
  234. not display anything if that estimate is for less than a few seconds.
  235. However, this is probably unnecessary.
  236.  
  237. @subsection Feedback and Control
  238.  
  239. The interface should provide visible feedback for every successful unit
  240. action initiated directly by the player, but it need not do so for failures,
  241. unless they are serious.  It is better to prevent nonsensical input,
  242. for instance by disabling menus and control panel items.  Simple interfaces
  243. such as for character terminals will have to relax these rules somewhat.
  244.  
  245. Interfaces should enable/disable display of lighting conditions.
  246.  
  247. @subsection Textual Displays
  248.  
  249. Text can take a long time to read, and can be difficult to provide
  250. in multiple human languages. (What, you thought only English speakers
  251. played @i{Xconq}?  Think again!)
  252. Therefore, text displays in the interfaces should be as minimal as
  253. possible, and derive from strings supplied in the game design,
  254. since they can be altered without rebuilding the entire program.
  255.  
  256. @subsection Display Update
  257.  
  258. Usually the interface's display is controlled by the player,
  259. but when @code{run_game} is executing, it will frequently change
  260. the state of an object in a way that needs to be reflected in the
  261. display immediately.  Examples include units leaving or entering
  262. a cell, sides losing or winning, and so forth.  The interface
  263. must define a set of callbacks that will be invoked by the kernel.
  264.  
  265. @code{update_cell_display(side, x, y, rightnow)}
  266.  
  267. [introduce area (radius or rect) update routines?]
  268.  
  269. @code{update_side_display(side, side2, rightnow)}
  270.  
  271. @code{update_unit_display(side, unit, rightnow)}
  272.  
  273. [etc]
  274.  
  275. Each of these routines has a flag indicating whether the change may be
  276. buffered or not.
  277. To ensure that buffered data is actually onscreen,
  278. the kernel may call @code{flush_display_buffers()}.
  279.  
  280. These may or may not be called on reasonable sides, so the
  281. interface should always check first that @code{side} actually
  282. exists and has an active display.
  283. [If side has a "remote" display, then interface has to forward??
  284. No, because remote copy of game is synchronized and does own
  285. update_xxx calls more-or-less simultaneously]
  286.  
  287. Note that this is as much as the kernel interests itself in displays.
  288. Map, list, etc drawing and redrawing are under the direct control
  289. of the interface code.
  290.  
  291. @subsection Types of Windows and Panels
  292.  
  293. @i{Xconq} is best with a window-style interface, either tiled
  294. or overlapping.  Overlapping is more flexible, but sometimes
  295. complicates understanding as players try to arrange them usefully.
  296. In the following discussion, "window" will refer to a logically
  297. unified part of the display, which can be either a window or a panel
  298. in some larger window.
  299.  
  300. The centerpiece window should be a map display.
  301. This will be the most-used window,
  302. since it will typically display more useful information
  303. than any other window.
  304. This means that it must also exhibit very good performance.
  305.  
  306. When a game starts up, the map display should be centered
  307. on one of the player's units, preferably one close to the
  308. center of all the player's units.
  309.  
  310. Another recommended window a list of all the sides and where
  311. they stand in both the current turn and in the game as a whole.
  312.  
  313. Overall status of side rules:
  314.  
  315. all grayed: out of game
  316.  
  317. grayed and x-ed out: lost
  318.  
  319. ???: won
  320.  
  321. Progress bar rules:
  322.  
  323. missing: no units or no ai/no display
  324.  
  325. grayed frame: no acting units
  326.  
  327. empty solid frame: all acted
  328.  
  329. part full, black: partly acted
  330.  
  331. part full, gray: finished turn
  332.  
  333. @subsection Imaging
  334.  
  335. Imaging is the process of drawing pictorial representations.
  336. Not every interface needs it, for instance the curses interface
  337. is limited to drawing two ASCII characters in a cell,
  338. which is the extent of its imaging.
  339. However, full-color bitmapped displays need more attention
  340. to the process of getting an image onscreen.
  341.  
  342. No graphical icon should be drawn smaller than about 8x8, unless it's
  343. a text character drawn in two contrasting colors.
  344.  
  345. Interfaces should cache optimal displays for each mag, not search
  346. for best image each time.
  347.  
  348. Could allow 1-n "display variants" for all images, and for each orientation of
  349. border and connection.
  350.  
  351. Imaging variations can be randomly selected by UI,
  352. but must be maintained so redraws are consistent.
  353.  
  354. Could allow the 64 bord/conn combos as single images, also advantage
  355. that all will be drawn at once.
  356.  
  357. @subsection Designer's Tools
  358.  
  359. An interface is not required to provide any sort of online
  360. designing tools, or even to provide a way to enable the
  361. special design privileges.  Nevertheless, minimal tools
  362. can be very helpful, and you will often find that they are
  363. helpful in debugging the rest of the interface, since you
  364. can use them to construct test cases at any time.
  365.  
  366. A basic set of design tools should include a way to enable
  367. and disable designing for at least one side, a command to
  368. create units of a given type, and some sort of tool to set
  369. the terrain type at a given location.  A full set would
  370. include ``painting'' tools for all area layers, including
  371. geographical features, materials, weather, side views,
  372. and so forth - about a dozen in all.
  373.  
  374. A least one level of undo for designer actions is very
  375. desirable, although it may be hard to implement.
  376. A useful rule for layers is to save a layer's previous
  377. state at the beginning of each painting or other modification
  378. action, when the mouse button first goes down.
  379.  
  380. The designer will often want to save only the part of the game
  381. being worked on, for instance only the units or only the terrain.
  382. The "save game" action should give designers a choice about
  383. what to save.  For units particularly, the designer should be
  384. able to save only some properties of units.  The most basic
  385. properties are type, location, side, and name/number.
  386. The unit id should not be saved by default, but should have
  387. its own option (not clear why).
  388.  
  389. Note that because game modules are textual and can be
  390. moved easily from one system to another, it is entirely
  391. possible to use one @i{Xconq} (perhaps on a Mac) to design
  392. games to be played on a Unix box under X11, or vice versa.
  393. Transferring the imagery is more difficult, although there
  394. is some support for the process.
  395.  
  396. @subsection Porting and Multiple Interfaces
  397.  
  398. In theory, it is possible to compile in multiple interfaces,
  399. but they would have to be multiplexed appropriately and not
  400. conflict anywhere in the address space.
  401. Sometimes this is intrinsically impossible;
  402. how could you compile the Mac and X interfaces into the same
  403. program, and would the result be a Mac application, a Unix program,
  404. or what?
  405.  
  406. The kernel/interface architecture could however be exploited to build
  407. a true server/client @i{Xconq},
  408. by building an ``interface'' that manages IPC connections
  409. and calling this the server, and then writing separate interface
  410. programs that translate data at the other end of the IPC connection
  411. into something that a display could use.
  412. My previous attempt at this was very slow and buggy,
  413. though, so this is not necessarily an easy thing to write.
  414. The chief problem is in keeping the client's view of thousands
  415. of interlinked objects (units, sides, cells, and so forth)
  416. consistent with the server.
  417. Most existing server/client games work by either restricting
  418. the state to a handful of objects,
  419. or by only handing the client display-prepared data
  420. rather than abstract data,
  421. or by reducing the update interval
  422. to minutes or hours.
  423.  
  424. @subsection Guidelines and Suggestions
  425.  
  426. Although as the interface builder, you are free to make it work in any
  427. way you like, there are a number of basic things you should do.
  428. Some of these are general user interface principles, others are specific
  429. to @i{Xconq}, usually based on experiences with the existing interfaces.
  430. Applying some of these guidelines will require judicious balancing between
  431. consistency with the different version of @i{Xconq} and consistency with
  432. the system you're porting to.
  433.  
  434. [following items should be better organized, moved in with relevant sections]
  435.  
  436. There should always be some sort of "what's happening now" display
  437. so player doesn't wonder about apparently dead machine.
  438.  
  439. Interfaces should ensure stability of display choices
  440. if random possibilities, so need to cache local decisions about
  441. appearance of units if multiple images to choose from, choice of
  442. text messages, etc.
  443.  
  444. Rules of Interaction:
  445. 1. Player can get to any unit in any mode.
  446. 2. Any player can prevent a turn from completing(/progressing?),
  447.    unless a hard real limit is encountered.
  448. 3. All players see each others' general move/activity state, modes, etc.
  449. 4. Players can "nudge" each other.
  450. 5. Real time limits can be set for sides, turns, and games, both by players
  451.    and by scenarios.
  452.  
  453. Both standard and nonstandard variants should vanish from dialog boxes
  454. if irrelevant to a selected game.
  455.  
  456. Player should be able to click on a desired unit or image, and effectively
  457. say "take this", either grabs directly or else composes a task to approach
  458. and capture.
  459.  
  460. Side lists should be adjusted to accommodate all scores being kept.
  461.  
  462. Allow for some kind of "face" or group of faces/expressions for a side,
  463. so get a barbarian's face to repn a side instead of generic.
  464. Could have interface generate remarks/balloons if face clicked on,
  465. perhaps a reason for feelings, slogan, citation of agreement or broken
  466. agreement, etc.
  467. Need 5 faces for hostile, unfavorable, neutral, favorable, friendly/trusting.
  468.  
  469. Unit closeups should be laid out individually for each type, too much
  470. variability to make a single format reasonable.
  471.  
  472. Add option where game design can specify use or avoidance of masks
  473. with unit icons.
  474.  
  475. Player could escape a loss by saving a game, then discarding save.
  476. Mplayers could register suspicion when player saves then quits -
  477. "You're not trying to cheat, are you?" - but can't prevent this.
  478.  
  479. All interfaces should be able to bring up an "Instructions" window
  480. that informs player(s) about the current game, includes xrefs to all
  481. game design info.  Restrict help to generic and interface info only.
  482.  
  483. Graph display should graphing of various useful values, such as amounts
  484. of units and materials over time, attitudes of sides, combat, etc.
  485. Maximal is timeline for all sides and units, usually too elaborate but
  486. allow tracking movement for some "important" units.  Note that move
  487. actions may be recorded anyway.
  488.  
  489. Make specialized dialog for agreements, put name on top, then scrolling list of
  490. terms, then signers, then random bits (public/secret, etc).  Use for proposals
  491. also, so allow for "tentative" signers, desired signers who have not looked at
  492. agreement.  Be able to display truth of each term, but need test to know when
  493. a side can know the truth of a term?
  494.  
  495. A quit cmd can always take a player out of the game, but player may have
  496. to agree to resign.  Player can also declare willingness to quit or draw
  497. without actually doing so, then resolution requires that everybody agree.
  498. If quitting but others continuing on, also have option of being a
  499. spectator.  Could have notion of "leaving game without declaring entire
  500. game a draw" for some players.
  501. Allow for a timeout and default vote in case some voters have disappeared
  502. mysteriously.
  503. Must never force a player to stay in.
  504. Add a notion of login/logout so a side can be inactive but untouchable,
  505. possibly freezes entire game if a side is inactive.
  506. 1. if one player or no scoring
  507.     confirm, then shut player down
  508.     if one player, then shut game down
  509. 2. if side is considered a sure win (how to tell? is effectively a win
  510. condition then) or all sides willing to draw
  511.     confirm, take side out, declare a draw, shut player down
  512. 3. if all sides willing to quit
  513.     take entire game down
  514. 4. ask about resigning - if yes,
  515.     resign, close display, keep game running
  516.    if no, ask if willing to quit and/or draw, send msg to other sides
  517. Kernel support limited to must_resign_to_quit(side), similar tests.
  518.  
  519. Interfaces should have a ``wake up dummy'' button that can be used by players
  520. who have finished their turn, to prod other players not yet done.
  521.  
  522. Commands that are irrelevant for a game ought to be grayed out in
  523. help displays, and error messages should identify as completely invalid
  524. (or just not do anything, a la grayed Mac menu shortcuts).
  525.  
  526. Prefixed number args should almost always be repetitions.
  527.  
  528. Should be able to drag out a route and have unit follow it (user input
  529. of a complete task sequence).
  530.  
  531. Hack formatting so that variable-width fonts usually work reasonably.
  532.  
  533. Add xref buttons to various windows to go to other relevant windows and
  534. focus in.
  535.  
  536. Draw partial cells around edges of a window, to indicate that the world
  537. continues on in that direction.
  538.  
  539. The current turn or date should be displayed prominently and be visible
  540. somewhere by default.
  541.  
  542. Add some high-level verbs as commands ("assault Berlin", "bomb London until
  543. destroyed").
  544.  
  545. Interface needs to draw *only* the terrain in edge cells.
  546. For cells along an edge with a bg gray (a la Mac), draw a heavy edge
  547. between cell and nothingness, diff from cell and unseen cells.
  548.  
  549. Could draw grid by blitting large light pattern over world, do by inverting
  550. so is easy to turn on/off.  Do grids by changing hex size only in
  551. unpatterned color?
  552.  
  553. Draw large hexagon or rect in unseen-color after clearing window to bg
  554. stipple (if unseen-color different).  Polygon should be inside area
  555. covered by edge hexes, so unseen area more obvious.
  556. Make large unseen-pattern that includes question marks?
  557.  
  558. Don't draw outline boxes at mags that would let them get outside the hex.
  559.  
  560. If dating view data, allow it to gray out rather than disappear entirely.
  561. Could even have a "fade time" for unit images...
  562.  
  563. Even if display is textual, use red text (and other colors) to indicate
  564. dangerous conditions.
  565.  
  566. If picture not defined for a game, use some sort of nondescript image
  567. instead of leaving blank. (small "no picture available" for instance,
  568. like in yearbooks)
  569.  
  570. Next/prev unit controls should change map focus, even if screen
  571. unaffected.
  572.  
  573. In general, ability to "select" a unit implies ability to examine,
  574. but not control.  Control implies ability to select, however.
  575.  
  576. Connections may need to be drawn differently in each of the two hexes
  577. they involve, such as straits connecting to a sea.
  578. (what is this supposed to mean?)
  579.  
  580. To display night, could invert everything (b/w) or do 25/50% black (color)
  581. (let game set, so some games could be all-black at night, nothing visible)
  582. (have day/night coverage for each utype?)
  583.  
  584. If cell cramped for space, show only one material type at a time,
  585. require redraw to show amounts of a different type.
  586.  
  587. Draw time remaining both digitally and as hourglass, for all time
  588. limits in effect.
  589.  
  590. Could tie map to follow a specified unit (or to flip there quickly
  591. a la SimAnt).
  592.  
  593. Have a separate message window from notices, allow broadcasting w/o
  594. specific msg command? (a "talk" window)
  595.  
  596. To display elevation, use deep blue -> light gray -> dark brown progression,
  597. maybe also contour lines?
  598. To draw contour lines, for each hex, look at each adj hex.  If on other
  599. side of contour's elev, compute interpolated point (in pixels) and save
  600. or draw a line to (one or both of the two) adj hex borders if they also
  601. have the contour line pass through.  Guaranteed that line is part of
  602. overall contour line.  Cheaper approach doesn't interpolate, just draws
  603. to midpoint of hex border (probably OK for small mags).
  604. Could maybe save contour lines once calculated (at each mag, lots of mem).
  605.  
  606. Redraw hexes exposed when a unit with a legend moves.
  607. Truncate or move legend if would overlap some other unit/legend.
  608.  
  609. Put limits on the number of windows of each type, set up so will reuse
  610. windows, except for ones that are "staked down".
  611.  
  612. Fix border removal so inter-hex boundary pixels are cleaned up also.
  613.  
  614. Need a specialized window or display to check on current scores
  615. (showing actual situation vs what's still needed).
  616. (Show both scorekeepers actually in force, as well as the others.)
  617. Side display could also display scores relevant to that side.
  618.  
  619. Every unit plan display should have a place to record notes and general
  620. info about the unit, add a slot to units also.  Use in scenarios.
  621.  
  622. Need a command for when a player can explicitly change the self-unit.
  623.  
  624. Players should be able to rename any named object.  The interface should
  625. also provide a button or control to run any namer that might be available
  626. to the unit.
  627.  
  628. @subsection Versioning Standards
  629.  
  630. In version @var{7.x.y}, @var{x} should change only
  631. when some documented user-visible aspect of @i{Xconq} changes,
  632. whether in the interface or kernel.
  633. @var{y} is reserved for bug-fix releases, which can include
  634. the implementation of features deliberately left unimplemented.
  635.  
  636. @section Pitfalls
  637.  
  638. This chapter would not be complete without some discussion of the traps
  639. awaiting the unwary hacker.
  640. The Absolute Number One Hazard in hacking @i{Xconq} is to introduce
  641. code that does not work for @emph{all} game designs.
  642. It is all too easy to assume that, for instance, unit speeds are always
  643. less than 20, or airbases can only be built by infantry, or that worlds
  644. are always randomly-generated.
  645. These sorts of assumptions have caused no end of crashes.
  646. Code should test preconditions, especially for dynamically-allocated
  647. game-specified objects, and it should be tested using the various
  648. test scripts in the test directory.
  649.  
  650. The number two pitfall is to not account for all the possible interfaces.
  651. Not all interfaces have a single ``current unit'' or map window,
  652. and some communicate with multiple players or over a network connection.
  653.  
  654. You should not assume that your hack is generally valid until you have
  655. tested it against everything in the library and test directories.
  656. The @code{test} directory contains scripts that will be useful for this,
  657. at least to Un*x hackers.
  658.  
  659. Another pitfall is to be sloppy about performance.  An algorithm that works
  660. fine in a small world with two sides and 50 units may be painfully slow
  661. in a large game. Or, the algorithm may allocate too much working space
  662. and wind up exhausting memory (this has happened).
  663. You should familiarize yourself with the algorithms already used in @i{Xconq},
  664. since they have already been debugged and tuned, and many have been written
  665. as generically useful code (see @code{world.c} for instance).
  666.  
  667. If your new feature is expensive, then define an efficient have_xxx()
  668. test that can be called from relevant places.
  669.  
  670. If time/effort to do action is > length of game, then interface
  671. can disable that action permanently.
  672.  
  673. Use moving bar or gray under black to indicate reserve/asleep units.
  674.  
  675. @section Rationale and Future Directions
  676.  
  677. This is where I justify everything I've done.
  678.  
  679. Please note that although @i{Xconq} has considerable power,
  680. its design was expressly limited to a particular class of two-dimensional
  681. board-like strategy games, and that playability  is emphasized over
  682. generality.  For instance, I avoided the temptation to include a
  683. general-purpose language, since it opens up many difficult issues
  684. and makes it much harder for game designers to produce a desired
  685. game (after all, if game designers wanted to use a general-purpose
  686. programming language, they could just write C code!).  Similarly,
  687. full 3D, realtime maneuvering, continuous terrain, and other such goodies
  688. must await the truly ultimate game system.
  689.  
  690. The real problem with a general-purpose language is that although
  691. everything is possible, nothing is easy.  Many ``adventure game
  692. writing systems'' have fallen into this trap; they end up being
  693. poor reimplementations of standard programming languages, and the
  694. sole support for adventure gaming amounts to a small program
  695. skeleton and a few library functions.  It would have been easier
  696. just to start with a pre-existing language and just write the
  697. skeleton and libraries!
  698.  
  699. @i{Xconq}, on the other hand, provides extensive optimized support
  700. for random game setup, large numbers of units, game save/restore,
  701. computer opponents, and many other facets of a game.
  702. Game designers don't have to deal with
  703. the subleties of fractal terrain synthesis, or the ordering of
  704. terrain effects on units, or how to tell the computer opponents
  705. that airbases are sometimes good for refueling but never any
  706. good for transportation, or the myriad of other details that
  707. are wired into @i{Xconq}.
  708. In fact, a complete working game can be set up with less than
  709. a half-page of GDL.
  710.  
  711. Even so, the current @i{Xconq} design allows for several layers
  712. of extensibility, as was described earlier in this chapter.
  713.  
  714. There are also several major areas in which @i{Xconq}
  715. could be improved.
  716.  
  717. Tables should be supplemented with general formulae, although
  718. such formulae will complicate AIs' analyses considerably,
  719. since tables are much easier to scan.
  720.  
  721. Currently everything is based on a single area of a single world.
  722. This could be extended to multiple areas in the world, perhaps
  723. at different scales, as well as to multiple worlds.
  724.